/*  Copyright 2003  Auri Marcelo Rizzo Vicenzi, Marcio Eduardo Delamaro, 			    Jose Carlos Maldonado

    This file is part of Jabuti.

    Jabuti is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as 
    published by the Free Software Foundation, either version 3 of the      
    License, or (at your option) any later version.

    Jabuti is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Jabuti.  If not, see <http://www.gnu.org/licenses/>.
*/


package br.jabuti.cmdtool;


import java.io.*;
import br.jabuti.criteria.*;
import br.jabuti.project.*;
import br.jabuti.util.*;


/**
 This application program prints the all-uses testing requirement for the
 entire project. It is necessary to specify the project name and the 
 desired all-uses criterion, all-uses-exception-independent or 
 all-uses-exception-dependent, 
 represented by the parameter -auei and -aued, respectively. 
 The program assume the -auei option by default.

 For example, by running the following command, considering 
 the project name "test.jbt" and the criterion primary-all-uses, 
 the table below is obtained.

	$ java -cp ".;lib\BCEL.jar;lib\jviewsall.jar" cmdtool.PrintRequirementsTable -auei -P test.jbt

 The resultant output is:
 
	1       1       0       <L@5, 71,71>
	1       1       1       <L@5, 46,58>
	1       1       2       <L@5, 71,58>
	1       1       3       <L@4, 0,41>
	1       1       4       <L@6, 58,58>
	1       1       5       <L@6, 52,58>
	1       1       6       <L@3, 0,28>
	1       1       7       <L@1, 0,28>
	1       1       8       <L@1, 0,21>
	1       1       9       <L@6, 58,(65, 71)>
	1       1       10      <L@6, 58,(65, 58)>
	1       1       11      <L@5, 46,(74, 52)>
	1       1       12      <L@5, 46,(74, 80)>
	1       1       13      <L@4, 0,36>
	1       1       14      <L@6, 52,(65, 71)>
	1       1       15      <L@6, 52,(65, 58)>
	1       1       16      <L@5, 46,71>
	1       1       17      <L@5, 71,(74, 80)>
	1       1       18      <L@5, 71,(74, 52)>
	1       2       0       <L@0, 0,15>
 
	where:
		1 column is the class_id;
		2 column is the method_id, inside a given class;
		3 column is the requirement number;
		4 column is the corresponding testing requirement.

<P>
		
Observe that information about the class_id and method_id can
be obtained by running {@link PrintClassMethodTable}.

@version: 0.00001
@author: Auri Marcelo Rizzo Vincenzi

*/
public class PrintRequirementsTable {
    public static void usage() {
        System.out.println(ToolConstants.toolName + " v. " + ToolConstants.toolVersion);
        System.out.println("\nPrintRequirementsTable usage:");
        System.out.println("-------------------\n");
        System.out.println("java cmdtool.PrintRequirementsTable [-d <DIR>] -anei|-aned|-aeei|-aeed|-auei|-aued|-apuei|-apued -p <PROJECT_NAME>\n");
        System.out.println("      [-d <DIR>]              Optional parameter. Specify the directory where the project");
        System.out.println("                              is located. If not specified, the current directory is assumed.");
		System.out.println("      -anei                   reports the required elements by the all-nodes-exception-independent criterion.");
		System.out.println("      -aned                   reports the required elements by the all-nodes-exception-dependent criterion.");
		System.out.println("      -aeei                   reports the required elements by the all-edges-exception-independent criterion.");
		System.out.println("      -aeed                   reports the required elements by the all-edges-exception-dependent criterion.");
		System.out.println("      -auei                   reports the required elements by the all-uses-exception-independent criterion.");
		System.out.println("      -aued                   reports the required elements by the all-uses-exception-dependent criterion.");
		System.out.println("      -apuei                  reports the required elements by the all-potential-uses-exception-independent criterion.");
		System.out.println("      -apued                  reports the required elements by the all-potential-uses-exception-dependent criterion.");        
		System.out.println("      -p <PROJECT_NAME>       Specify the name of the project to be used. The");
        System.out.println("                              project must be a valid project file (.jba) generated by");
        System.out.println("                              instrument the base class.");
        System.out.println("\nCopyright (c) 2002\n");
    }

    public static void main(String args[]) throws Throwable {
		
        String workDir = null;
        String projectName = null;
						
        JabutiProject project = null;

        boolean validCriterion = false;
        int criterionId = -1;
		
        if (args.length > 0) {

            int i = 0;
			
            while ((i < args.length) && (args[i].startsWith("-"))) {
                // selected criterion
                if (("-anei".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.PRIMARY_NODES;
                	validCriterion = true;
                } 
                else if (("-aned".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.SECONDARY_NODES;
                	validCriterion = true;
                } 
				else if (("-aeei".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.PRIMARY_EDGES;
                	validCriterion = true;
                } 
                else if (("-aeed".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.SECONDARY_EDGES;
                	validCriterion = true;
                }
                else if (("-auei".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.PRIMARY_USES;
                	validCriterion = true;
                } 
                else if (("-aued".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.SECONDARY_USES;
                	validCriterion = true;
                }                
                else if (("-apuei".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.PRIMARY_POT_USES;
                	validCriterion = true;
                } 
                else if (("-apued".equals(args[i])) && (i < args.length - 1)) {
                	criterionId = Criterion.SECONDARY_POT_USES;
                	validCriterion = true;
                }                
                
                // -d: work directory
                else if (("-d".equals(args[i])) && (i < args.length - 1)) {
                    i++;
                    workDir = args[i];
                } // -p: project name
                else if (("-p".equals(args[i])) && (i < args.length - 1)) {
                    i++;
                    projectName = args[i];
                } else {
                    System.out.println("Error: Unrecognized option: " + args[i]);
                    System.exit(0);
                }
                i++;
            }

            // Checking if all essential parameters are not null
            if (projectName == null) {
                System.out.println("Error: Missing parameter!!!");
                usage();
                System.exit(0);
            }

            // Checking if any valid testing criterion was speficied
            if (!validCriterion) {
                System.out.println("Invalida testing criteria!!!");
                usage();
                System.exit(0);
            }

            // Creating the absolute path to a given project
            String absoluteName = null;

            if (workDir != null) {
                absoluteName = workDir + File.separator + projectName;
            } else {
                absoluteName = projectName;
            }

            try {
                File theFile = new File(absoluteName);

                if (!theFile.isFile()) // verifica se existe
                {
                    System.out.println("File " + theFile.getName() + " not found");
                    System.exit(0);
                }
	          	
                project = JabutiProject.reloadProj( theFile.toString(), true );
 				
                // For each class
                String[] classFileNames = project.getAllClassFileNames();

                for (i = 0; i < classFileNames.length; i++) {
                    ClassFile cf = project.getClassFile(classFileNames[i]);
                
                    // For each method
                    String[] methodsNames = cf.getAllMethodsNames();
					
					if ( methodsNames != null ) {
	                    for (int j = 0; j < methodsNames.length; j++) {
	                        ClassMethod cm = cf.getMethod(methodsNames[j]);
	                		
	                        Criterion criterion = cm.getCriterion( criterionId );
							
	                        Object req[] = criterion.getRequirements();
	
	                        for (int c = 0; c < req.length; c++) {
	                            System.out.println(cf.getClassId() + "\t" + cm.getMethodId() + "\t" + c + "\t" + req[c]);
	                        }
	                    }
	                }
                }
            } catch (Exception e) {
                ToolConstants.reportException(e, ToolConstants.STDERR);
                System.exit(0);
            }
        } else {
            usage();
        }
    }
}
